﻿### Язык Барсик

Барсик являеется встроенным языком - "клеем", служащим для связки модулей в приложении, написания простых сценариев автоматизации и для конфигурирования приложений. Барсик не предназначен для создания полноценных приложений.

Барсик - это процедурный динамически типизированный модульный язык, работающий поверх платформы .NET.

Во многом он аналогичен языку Lua, однако, в отличие от Lua, привязан к платформе .NET.

#### Синтаксис

Синтаксис Барсика свободный, команды в тексте программы разделяются пробельными символами (при желании программист может использовать точку с запятой для разделения команд).

Идентификаторы начинаются с любого символа Unicode-классов `Ll` (строчные буквы) и `Lu` (прописные буквы), прочие символы идентификатора могут быть из классов `Ll`, `Lu`, `Nd` (десятичные цифры) и символ подчеркивания `_`. Барсик различает регистр символов в идентификаторах.

#### Типы данных

Барсик использует общую систему типов .NET. В частности, Барсик умеет работать со следующими типами данных:

* `null` (нулевой указатель);
* логический тип: `boolean`;
* целые со знаком: `int`, `short`, `long`, `sbyte`;
* целые без знака: `uint`, `ushort`, `ulong`, `byte`;
* числа с плавающей точкой: `float`, `double`;
* числа с фиксированной точкой: `decimal`;
* отдельный символ (буква): `char`;
* строка: `string`;
* дата/время: `datetime`;
* массив (одномерный): `array`;
* словарь: `dictionary`;
* делегат: `delegate`;
* объект - все прочие типы.

#### Формальная грамматика

```
ПРОГРАММА ::= [ ДИРЕКТИВЫ ] (ФУНКЦИЯ | КОМАНДА)+

ДИРЕКТИВА ::= "#r " ССЫЛКА_НА_СБОРКУ
    | "#l " ССЫЛКА_НА СКРИПТ
    | "#u " ПРОСТРАНСТВО_ИМЕН

ФУНКЦИЯ ::= "function" ИДЕНТИФИКАТОР (АРГУМЕНТЫ)
    "{" { КОМАНДА | ВОЗВРАТ } "}"

ВОЗВРАТ ::= "return" [ВЫРАЖЕНИЕ]

КОМАНДА ::= ПРИСВАИВАНИЕ
    | УСЛОВНЫЙ_ОПЕРАТОР
    | ЦИКЛ_ДЛЯ

ЦИКЛ_ДЛЯ ::= for ИНИЦИАЛИЗАЦИЯ ";" УСЛОВИЕ_ЦИКЛА ";" ИТЕРАЦИЯ
    "{" КОМАНДЫ "}"

УСЛОВНЫЙ_ОПЕРАТОР ::= "if" ЛОГИЧЕСКОЕ_ВЫРАЖЕНИЕ "{" { КОМАНДЫ } "}"
    [ "else" "{" КОМАНДЫ "}"

ПРИСВАИВАНИЕ ::= ИДЕНТИФИКАТОР ДЕЙСТВИЕ ВЫРАЖЕНИЕ

ДЕЙСТВИЕ ::= "=" | "+=" | "-=" | "*=" | "/=" | "%="

ВЫРАЖЕНИЕ ::= ПРЕОБРАЗОВАНИЕ_ТИПА
    | УНАРНОЕ_ВЫРАЖЕНИЕ
    | БИНАРНОЕ_ВЫРАЖЕНИЕ
    | СОЗДАНИЕ
    | ИНИЦИАЛИЗАЦИЯ_МАССИВА
    | ИНИЦИАЛИЗАЦИЯ_СЛОВАРЯ

ИНИЦИАЛИЗАЦИЯ_СЛОВАРЯ ::= "{" { ПАРЫ } "}"

ПАРА ::= КЛЮЧ ":" ВЫРАЖЕНИЕ

ИНИЦИАЛИЗАЦИЯ_МАССИВА ::= "[" АРГУМЕНТЫ "]"

СОЗДАНИЕ ::= "new" ИМЯ_ТИПА "(" АРГУМЕНТЫ ")"

АРГУМЕНТЫ ::= [ ВЫРАЖЕНИЕ { "," ВЫРАЖЕНИЕ } ]

ПРЕОБРАЗОВАНИЕ_ТИПА ::= ИМЯ_ТИПА "(" ВЫРАЖЕНИЕ ")"

ВЫЗОВ_ФУНКЦИИ ::= (ИДЕНТИФИКАТОР | ОБРАЩЕНИЕ_К_ЧЛЕНУ) "(" АРГУМЕНТЫ ")"

УНАРНОЕ_ВЫРАЖЕНИЕ ::= УНАРНЫЙ_ОПЕРАТОР ИДЕНТИФИКАТОР
    | УНАРНЫЙ_ОПЕРАТОР "(" ВЫРАЖЕНИЕ ")"
    | УНАРНЫЙ_ОПЕРАТОР УНАРНОЕ_ВЫРАЖЕНИЕ
    | ОБРАЩЕНИЕ_К_ЧЛЕНУ

ОБРАЩЕНИЕ_К_ЧЛЕНУ ::= ВЫРАЖЕНИЕ '.' ИДЕНТИФИКАТОР

УНАРНЫЙ_ОПЕРАТОР ::= '+' | '-' | '!'

БИНАРНОЕ_ВЫРАЖЕНИЕ ::= УРОВЕНЬ_1 СЛОЖЕНИЕ УРОВЕНЬ_1

УРОВЕНЬ_1 ::= УРОВЕНЬ_2 УМНОЖЕНИЕ УРОВЕНЬ_2

УРОВЕНЬ_2 ::= ДОСТУП_ПО_ИНДЕКСУ
    | ВЫЗОВ_ФУНКЦИИ
    | "(" ВЫРАЖЕНИЕ ")"
    | УРОВЕНЬ_3

УРОВЕНЬ_3 ::= ИДЕНТИФИКАТОР | ЛИТЕРАЛ

ДОСТУП_ПО_ИНДЕКСУ ::= УРОВЕНЬ_3 "[" ВЫРАЖЕНИЕ "]"

СЛОЖЕНИЕ ::= '+' | '-'

УМНОЖЕНИЕ ::= '*' | '/' | '%'

ИДЕНТИФИКАТОР ::= ( БУКВА | '_' ) { БУКВА | ЦИФРА | '_' }

ЛИТЕРАЛ ::= ЛОГИЧЕСКИЙ_ЛИТЕРАЛ
    | ЦЕЛОЧИСЛЕННЫЙ_ЛИТЕРАЛ
    | ПЛАВАЮЩИЙ_ЛИТЕРАЛ
    | ФИКСИРОВАННЫЙ_ЛИТЕРАЛ
    | СТРОКОВЫЙ_ЛИТЕРАЛ

ЛОГИЧЕСКИЙ_ЛИТЕРАЛ ::= 'true' | 'false'

ЦЕЛОЧИСЛЕННЫЙ_ЛИТЕРАЛ ::= ['-'] (цифры | HEX) [ СУФФИКС ]

HEX ::= ("0x" | "0X") [0-9abcdefABCDEF]+

СУФФИКС ::= "u" | "U" | "l" | "L" | "ul" | "UL" | "lu" | "LU"
    | "s" | "S" | "us" | "US" | "su" | "SU"

ПЛАВАЮЩИЙ_ЛИТЕРАЛ ::= ['-'] цифры ['.' цифры] [('E' | 'e') ['-' | '+'] цифры] ['f' | 'F' | 'd' | 'D']

ФИКСИРОВАННЫЙ_ЛИТЕРАЛ ::= ['-'] цифры ['.' цифры] ('m' | 'M')

СТРОКОВЫЙ_ЛИТЕРАЛ ::= '"' символы '"'
    | '@' '"' символы '"'

КОММЕНТАРИЙ ::= "//" текст
    | "/*" текст "*/"

```

#### Примеры программ

Простейшая:

```
println("Hello, world!")
```

С циклом:

```
x = 1
for i = 0; i < 10; i = i + 1 {
    x = x * 2
}

println("Результат равен: ", x)
```

С условным оператором:

```
if x > 0 {
    println("Положительное число")
}
else {
    println("Отрицательное или 0")
}
```
